//
//  TYSegementCell.m
//  TYUIKit
//
//  Created by TuyaInc on 2019/2/28.
//

#import "TYSegmentCell.h"
#import "UIView+TYFrame.h"
#import "TYSegmentAnimator.h"
#import "TYUIKit/TYUIKit-umbrella.h"

static CGFloat const kRedPointRadius = 3.f;

@implementation TYSegmentCellModel

@end

@interface TYDashView : UIView
@property(nonatomic,strong)CAShapeLayer* dashLayer;
@end

@implementation TYDashView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self drawDashLine:self lineLength:2 lineSpacing:2 lineColor:[UIColor ty_colorWithHex:0x999999]];
    }
    return self;
}

/**
 ** lineView:       需要绘制成虚线的view
 ** lineLength:     虚线的宽度
 ** lineSpacing:    虚线的间距
 ** lineColor:      虚线的颜色
 **/
- (void)drawDashLine:(TYDashView *)lineView lineLength:(int)lineLength lineSpacing:(int)lineSpacing lineColor:(UIColor *)lineColor
{
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    [shapeLayer setBounds:lineView.bounds];
    [shapeLayer setPosition:CGPointMake(CGRectGetWidth(lineView.frame) / 2, CGRectGetHeight(lineView.frame))];
    [shapeLayer setFillColor:[UIColor clearColor].CGColor];
    
    //  设置虚线颜色为
    [shapeLayer setStrokeColor:lineColor.CGColor];
    
    //  设置虚线宽度
    [shapeLayer setLineWidth:MIN(lineView.ty_width, lineView.ty_height)];
    [shapeLayer setLineJoin:kCALineJoinRound];
    
    //  设置线宽，线间距
    [shapeLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithInt:lineLength], [NSNumber numberWithInt:lineSpacing], nil]];
    
    //  设置路径
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 0, 0);
    CGPathAddLineToPoint(path, NULL, CGRectGetWidth(lineView.frame), 0);
    
    [shapeLayer setPath:path];
    CGPathRelease(path);
    lineView.dashLayer = shapeLayer;
    //  把绘制好的虚线添加上来
    [lineView.layer addSublayer:shapeLayer];
}

@end

@interface TYSegmentCharacterCell : UICollectionViewCell
@property(nonatomic,strong)TYDashView* horDashView;
@property(nonatomic,strong)TYDashView* verDashView;
@property(nonatomic,strong)UILabel* titleLabel;
@property(nonatomic,strong)UIView* leftLine;
@end

@implementation TYSegmentCharacterCell

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.horDashView = [[TYDashView alloc]initWithFrame:CGRectMake(0, (frame.size.height - 0.5) / 2, frame.size.width, 0.5)];
        [self addSubview:self.horDashView];
        self.verDashView = [[TYDashView alloc]initWithFrame:/*CGRectMake((frame.size.width - 0.5) / 2, 0, 0.5, frame.size.height)*/self.horDashView.frame];
        [self addSubview:self.verDashView];
        self.verDashView.transform =  CGAffineTransformMakeRotation(M_PI_2);
        UILabel* titleLabel = [[UILabel alloc]init];
        titleLabel.textColor = [UIColor ty_colorWithHex:0x222222];
        titleLabel.font = [UIFont systemFontOfSize:TY_ScreenAdaptionLength(20) weight:UIFontWeightBold];
        self.titleLabel = titleLabel;
        titleLabel.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
        titleLabel.textAlignment = NSTextAlignmentCenter;
        [self addSubview:titleLabel];
        
        UIView* leftLine = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 0.5, frame.size.height)];
        self.leftLine = leftLine;
        [self addSubview:leftLine];
    }
    return self;
}

-(void)updateViewWithTitle:(NSString*)title index:(NSInteger)index isSelected:(BOOL)isSelected{
    self.titleLabel.text = title;
    self.leftLine.hidden = index == 0;
    self.leftLine.backgroundColor = isSelected ? [UIColor ty_colorWithHex:0x359EFC] : [UIColor ty_colorWithHex:0x999999];
    [self.horDashView.dashLayer setStrokeColor:self.leftLine.backgroundColor.CGColor];
    [self.verDashView.dashLayer setStrokeColor:self.leftLine.backgroundColor.CGColor];
}



@end

@interface TYSegmentCharacterTableView : UIView<UICollectionViewDelegateFlowLayout, UICollectionViewDataSource>
@property(nonatomic,strong)NSArray<NSString*>* dataList;
@property(nonatomic,strong)UICollectionView* collectionView;
@property(nonatomic,assign)BOOL isSelected;
@property(nonatomic,copy)void (^selectedCallback)(void);
@end

@implementation TYSegmentCharacterTableView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self configureUI];
    }
    return self;
}
static NSString* cellIdentifier = @"cell";
-(void)configureUI {
    UICollectionViewFlowLayout* layout = [[UICollectionViewFlowLayout alloc]init];
    layout.itemSize = TY_ScreenAdaptionSize(CGSizeMake(45, 45));
    layout.minimumInteritemSpacing = 0;
    layout.minimumLineSpacing = 0;
    
    UICollectionView* collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, 0, 0) collectionViewLayout:layout];
    self.collectionView = collectionView;
    collectionView.delegate = self;
    collectionView.dataSource = self;
    collectionView.showsVerticalScrollIndicator = NO;
    collectionView.showsVerticalScrollIndicator = NO;
    [self addSubview:collectionView];
    [collectionView registerClass:[TYSegmentCharacterCell class] forCellWithReuseIdentifier:cellIdentifier];
}

- (void)layoutSubviews{
    [super layoutSubviews];
    self.collectionView.frame = self.bounds;
}

-(void)updateWithCellModel:(TYSegmentCellModel*)cellModel{
    NSString* titleString = cellModel.title;
    NSMutableArray* titleArr = [NSMutableArray arrayWithCapacity:titleString.length];
    for (int i = 0; i < titleString.length; i++) {
        NSString* str = [titleString substringWithRange:NSMakeRange(i, 1)];
        [titleArr addObject:str];
    }
    self.dataList = titleArr;
    BOOL isSelected = cellModel.selected;
    self.isSelected = isSelected;
    self.collectionView.backgroundColor = isSelected ? [UIColor ty_colorWithHex:0xE3F2FF] : [UIColor whiteColor];
    [self.collectionView reloadData];
    
    self.backgroundColor = isSelected ? [UIColor ty_colorWithHex:0xE3F2FF] : [UIColor whiteColor];
    BOOL isOnMac = NO;
    if (@available(iOS 14.0, *)) {
        isOnMac = [NSProcessInfo processInfo].isiOSAppOnMac;
    }
    self.layer.borderWidth = isOnMac? 1 : 0.5;
    self.layer.borderColor = (isSelected ? [UIColor ty_colorWithHex:0x359EFC] : [UIColor ty_colorWithHex:0x999999]).CGColor;
    self.layer.masksToBounds = YES;
    self.layer.cornerRadius = TY_ScreenAdaptionLength(10);
}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return self.dataList.count;
}

-(__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    TYSegmentCharacterCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
    [cell updateViewWithTitle:self.dataList[indexPath.item] index:indexPath.item isSelected:self.isSelected];
    return cell;
}

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    if (self.selectedCallback) {
        self.selectedCallback();
    }
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    return CGSizeMake(ceil(collectionView.ty_height), collectionView.ty_height);
}

@end

@interface TYSegmentCell ()

@property (nonatomic, strong) NSString *currentImageName;

@property (nonatomic, strong) UIView *redPoint;
@property (nonatomic, strong) CALayer *titleMaskLayer;
@property (nonatomic, strong) CALayer *maskTitleMaskLayer;
@property (nonatomic, strong) TYSegmentCellModel *cellModel;
@property (nonatomic, strong) TYSegmentAnimator *animator;
@property (nonatomic, strong) NSMutableArray <TYSegmentSelectedAnimationBlock> *animationBlockArray;

@property(nonatomic,strong)TYSegmentCharacterTableView* charcterView;


@end

@implementation TYSegmentCell


- (void)dealloc
{
    [self.animator stop];
}

- (void)prepareForReuse {
    [super prepareForReuse];
    
    [self.animator stop];
}

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.isAccessibilityElement = YES;
        self.accessibilityIdentifier = @"ty_segment";
        [self initViews];
    }
    return self;
}

- (void)initViews {
    _animationBlockArray = [NSMutableArray array];
    
    _titleLabel = [[UILabel alloc] init];
    self.titleLabel.clipsToBounds = YES;
    self.titleLabel.textAlignment = NSTextAlignmentCenter;
    [self.contentView addSubview:self.titleLabel];
    
    _imageView = [[UIImageView alloc] init];
    _imageView.contentMode = UIViewContentModeScaleAspectFit;
    [self.contentView addSubview:self.imageView];
    
    self.redPoint = [[UILabel alloc] init];
    self.redPoint.frame = CGRectMake(0, 0, kRedPointRadius * 2, kRedPointRadius * 2);
    self.redPoint.layer.cornerRadius = kRedPointRadius;
    self.redPoint.clipsToBounds = YES;
    self.redPoint.hidden = YES;
    self.redPoint.backgroundColor = [UIColor redColor];
    [self.contentView addSubview:self.redPoint];
    
    _titleMaskLayer = [CALayer layer];
    self.titleMaskLayer.backgroundColor = [UIColor redColor].CGColor;
    
    _maskTitleLabel = [[UILabel alloc] init];
    _maskTitleLabel.hidden = YES;
    self.maskTitleLabel.textAlignment = NSTextAlignmentCenter;
    [self.contentView addSubview:self.maskTitleLabel];
    
    _maskTitleMaskLayer = [CALayer layer];
    self.maskTitleMaskLayer.backgroundColor = [UIColor redColor].CGColor;
    self.maskTitleLabel.layer.mask = self.maskTitleMaskLayer;
    
    self.charcterView = [[TYSegmentCharacterTableView alloc]initWithFrame:CGRectZero];
    __weak typeof(self) weakSelf = self;
    [self.charcterView setSelectedCallback: ^{
        weakSelf.characterTableselectedCallback();
    }];
    [self.contentView addSubview:self.charcterView];
}

- (void)reloadData:(TYSegmentCellModel *)cellModel {
    self.cellModel = cellModel;
    if (cellModel.isCharacterTable) {
        self.charcterView.hidden = NO;
        [self.charcterView updateWithCellModel:cellModel];
        return;
    }
    self.charcterView.hidden = YES;
    if (cellModel.selected) {
        self.backgroundColor = cellModel.cellBackgroundSelectedColor;
    }else {
        self.backgroundColor = cellModel.cellBackgroundUnselectedColor;
    }
    if (cellModel.cellLayerRadius > 0) {
        self.layer.cornerRadius = cellModel.cellLayerRadius;
        self.layer.masksToBounds = YES;
    }else {
        self.layer.cornerRadius = 0;
    }
    if (cellModel.selectedAnimationEnabled) {
        [self.animationBlockArray removeLastObject];
        if ([self checkCanStartSelectedAnimation:cellModel]) {
            _animator = [[TYSegmentAnimator alloc] init];
            self.animator.duration = cellModel.selectedAnimationDuration;
        }else {
            [self.animator stop];
        }
    }
    
    TYSegmentCellModel *myCellModel = self.cellModel;
    self.redPoint.hidden = !myCellModel.showRedPoint;
    
    if (myCellModel.titleLabelZoomEnabled) {
        //先把font设置为缩放的最大值，再缩小到最小值，最后根据当前的titleLabelZoomScale值，进行缩放更新。这样就能避免transform从小到大时字体模糊
        UIFont *maxScaleFont = [UIFont fontWithDescriptor:myCellModel.titleSelectedFont.fontDescriptor size:myCellModel.titleFont.pointSize*myCellModel.titleLabelSelectedZoomScale];
        CGFloat baseScale = myCellModel.titleFont.lineHeight/maxScaleFont.lineHeight;
        if (myCellModel.selectedAnimationEnabled && [self checkCanStartSelectedAnimation:myCellModel]) {
            TYSegmentSelectedAnimationBlock block = [self preferredTitleZoomAnimationBlock:myCellModel baseScale:baseScale];
            [self addSelectedAnimationBlock:block];
        }else {
            self.titleLabel.font = maxScaleFont;
            self.maskTitleLabel.font = maxScaleFont;
            CGAffineTransform currentTransform = CGAffineTransformMakeScale(baseScale*myCellModel.titleLabelCurrentZoomScale, baseScale*myCellModel.titleLabelCurrentZoomScale);
            self.titleLabel.transform = currentTransform;
            self.maskTitleLabel.transform = currentTransform;
        }
    }else {
        if (myCellModel.selected) {
            self.titleLabel.font = myCellModel.titleSelectedFont;
            self.maskTitleLabel.font = myCellModel.titleSelectedFont;
        }else {
            self.titleLabel.font = myCellModel.titleFont;
            self.maskTitleLabel.font = myCellModel.titleFont;
        }
    }
    
    NSString *titleString = myCellModel.title ? myCellModel.title : @"";
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:titleString];
    if (myCellModel.titleLabelStrokeWidthEnabled) {
        if (myCellModel.selectedAnimationEnabled && [self checkCanStartSelectedAnimation:myCellModel]) {
            TYSegmentSelectedAnimationBlock block = [self preferredTitleStrokeWidthAnimationBlock:myCellModel attributedString:attributedString];
            [self addSelectedAnimationBlock:block];
        }else {
            [attributedString addAttribute:NSStrokeWidthAttributeName value:@(myCellModel.titleLabelCurrentStrokeWidth) range:NSMakeRange(0, titleString.length)];
            self.titleLabel.attributedText = attributedString;
            self.maskTitleLabel.attributedText = attributedString;
        }
    }else {
        self.titleLabel.attributedText = attributedString;
        self.maskTitleLabel.attributedText = attributedString;
    }
    
    if (myCellModel.titleLabelMaskEnabled) {
        self.maskTitleLabel.hidden = NO;
        self.titleLabel.textColor = myCellModel.titleNormalColor;
        self.maskTitleLabel.textColor = myCellModel.titleSelectedColor;
        [self.maskTitleLabel sizeToFit];
        
        CGRect topMaskframe = myCellModel.backgroundViewMaskFrame;
        //将相对于cell的backgroundViewMaskFrame转换为相对于maskTitleLabel
        //使用self.bounds.size.width而不是self.contentView.bounds.size.width。因为某些情况下，会出现self.bounds是正确的，而self.contentView.bounds还是重用前的状态。
        topMaskframe.origin.y = 0;
        CGRect bottomMaskFrame = topMaskframe;
        CGFloat maskStartX = 0;
        if (self.maskTitleLabel.bounds.size.width >= self.bounds.size.width) {
            topMaskframe.origin.x -= (self.maskTitleLabel.bounds.size.width -self.bounds.size.width)/2;
            bottomMaskFrame.size.width = self.maskTitleLabel.bounds.size.width;
            maskStartX = -(self.maskTitleLabel.bounds.size.width -self.bounds.size.width)/2;
        }else {
            bottomMaskFrame.size.width = self.bounds.size.width;
            topMaskframe.origin.x -= (self.bounds.size.width -self.maskTitleLabel.bounds.size.width)/2;
            maskStartX = 0;
        }
        bottomMaskFrame.origin.x = topMaskframe.origin.x;
        if (topMaskframe.origin.x > maskStartX) {
            bottomMaskFrame.origin.x = topMaskframe.origin.x - bottomMaskFrame.size.width;
        }else {
            bottomMaskFrame.origin.x = CGRectGetMaxX(topMaskframe);
        }
        
        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        if (topMaskframe.size.width > 0 && CGRectIntersectsRect(topMaskframe, self.maskTitleLabel.frame)) {
            self.titleLabel.layer.mask = self.titleMaskLayer;
            self.maskTitleMaskLayer.frame = topMaskframe;
            self.titleMaskLayer.frame = bottomMaskFrame;
        }else {
            self.maskTitleMaskLayer.frame = topMaskframe;
            self.titleLabel.layer.mask = nil;
        }
        [CATransaction commit];
    }else {
        self.maskTitleLabel.hidden = YES;
        self.titleLabel.layer.mask = nil;
        if (myCellModel.selectedAnimationEnabled && [self checkCanStartSelectedAnimation:myCellModel]) {
            TYSegmentSelectedAnimationBlock block = [self preferredTitleColorAnimationBlock:myCellModel];
            [self addSelectedAnimationBlock:block];
        }else {
            self.titleLabel.textColor = myCellModel.titleCurrentColor;
        }
    }
    
    if (self.currentImageName != self.cellModel.imageName) {
        UIImage *image = [UIImage imageNamed:self.cellModel.imageName inBundle:self.cellModel.imageBundle compatibleWithTraitCollection:nil];
        self.imageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
        self.currentImageName = self.cellModel.imageName;
    }
    
    if (myCellModel.selected) {
        self.imageView.tintColor = self.cellModel.titleSelectedColor;
    } else {
        self.imageView.tintColor = self.cellModel.titleNormalColor;
    }
    
    [self startSelectedAnimationIfNeeded:myCellModel];
    
    
    [self.titleLabel sizeToFit];
    [self layoutIfNeeded];
    [self setNeedsLayout];
}


- (void)layoutSubviews {
    [super layoutSubviews];
    self.charcterView.frame = self.bounds;
    BOOL hasImage = self.cellModel.imageName || self.cellModel.imageUrl;
    BOOL hasTitle = self.cellModel.title.length > 0;
    if (hasImage && hasTitle) {
        CGFloat y = (self.contentView.ty_height - self.cellModel.imageSize.height - self.cellModel.titleImageSpacing - self.titleLabel.ty_height) / 2.f;
        self.imageView.ty_size = self.cellModel.imageSize;
        self.imageView.ty_centerX = self.contentView.ty_width / 2.f;
        self.titleLabel.ty_centerX = self.contentView.ty_width / 2.f;
        self.imageView.ty_top = y;
        self.titleLabel.ty_top = y + self.cellModel.imageSize.height  + self.cellModel.titleImageSpacing;
    } else if (hasImage) {
        self.imageView.center = self.contentView.center;
        self.imageView.ty_size = self.cellModel.imageSize;
        self.redPoint.center = CGPointMake(self.imageView.ty_right + kRedPointRadius * 0.5, self.imageView.ty_top + kRedPointRadius * 0.5);
    } else if (hasTitle) {
        self.titleLabel.center = self.contentView.center;
        self.maskTitleLabel.center = self.contentView.center;
        //向下取整 避免圆角被裁切
        self.redPoint.center = CGPointMake(self.titleLabel.ty_right + kRedPointRadius, self.titleLabel.ty_top);
    }
}

- (TYSegmentSelectedAnimationBlock)preferredTitleZoomAnimationBlock:(TYSegmentCellModel *)cellModel baseScale:(CGFloat)baseScale {
    __weak typeof(self) weakSelf = self;
    return ^(CGFloat percent) {
        if (cellModel.selected) {
            //将要选中，scale从小到大插值渐变
            cellModel.titleLabelCurrentZoomScale = [TYSegmentAnimator interpolationFrom:cellModel.titleLabelNormalZoomScale to:cellModel.titleLabelSelectedZoomScale percent:percent];
        }else {
            //将要取消选中，scale从大到小插值渐变
            cellModel.titleLabelCurrentZoomScale = [TYSegmentAnimator interpolationFrom:cellModel.titleLabelSelectedZoomScale to:cellModel.titleLabelNormalZoomScale percent:percent];
        }
        CGAffineTransform currentTransform = CGAffineTransformMakeScale(baseScale*cellModel.titleLabelCurrentZoomScale, baseScale*cellModel.titleLabelCurrentZoomScale);
        weakSelf.titleLabel.transform = currentTransform;
        weakSelf.maskTitleLabel.transform = currentTransform;
    };
}

- (TYSegmentSelectedAnimationBlock)preferredTitleStrokeWidthAnimationBlock:(TYSegmentCellModel *)cellModel attributedString:(NSMutableAttributedString *)attributedString {
    __weak typeof(self) weakSelf = self;
    return ^(CGFloat percent) {
        if (cellModel.selected) {
            cellModel.titleLabelCurrentStrokeWidth = [TYSegmentAnimator interpolationFrom:cellModel.titleLabelNormalStrokeWidth to:cellModel.titleLabelSelectedStrokeWidth percent:percent];
        }else {
            cellModel.titleLabelCurrentStrokeWidth = [TYSegmentAnimator interpolationFrom:cellModel.titleLabelSelectedStrokeWidth to:cellModel.titleLabelNormalStrokeWidth percent:percent];
        }
        [attributedString addAttribute:NSStrokeWidthAttributeName value:@(cellModel.titleLabelCurrentStrokeWidth) range:NSMakeRange(0, attributedString.string.length)];
        weakSelf.titleLabel.attributedText = attributedString;
        weakSelf.maskTitleLabel.attributedText = attributedString;
    };
}

- (TYSegmentSelectedAnimationBlock)preferredTitleColorAnimationBlock:(TYSegmentCellModel *)cellModel {
    __weak typeof(self) weakSelf = self;
    return ^(CGFloat percent) {
        if (cellModel.selected) {
            //将要选中，textColor从titleNormalColor到titleSelectedColor插值渐变
            cellModel.titleCurrentColor = [TYSegmentAnimator interpolationColorFrom:cellModel.titleNormalColor to:cellModel.titleSelectedColor percent:percent];
        }else {
            //将要取消选中，textColor从titleSelectedColor到titleNormalColor插值渐变
            cellModel.titleCurrentColor = [TYSegmentAnimator interpolationColorFrom:cellModel.titleSelectedColor to:cellModel.titleNormalColor percent:percent];
        }
        weakSelf.titleLabel.textColor = cellModel.titleCurrentColor;
    };
}

- (BOOL)checkCanStartSelectedAnimation:(TYSegmentCellModel *)cellModel {
    if (cellModel.selectedType == TYSegmentItemSelectTypeCode || cellModel.selectedType == TYSegmentItemSelectTypeClick) {
        return YES;
    }
    return NO;
}

- (void)addSelectedAnimationBlock:(TYSegmentSelectedAnimationBlock)block {
    [self.animationBlockArray addObject:block];
}

- (void)startSelectedAnimationIfNeeded:(TYSegmentCellModel *)cellModel {
    if (cellModel.selectedAnimationEnabled && [self checkCanStartSelectedAnimation:cellModel]) {
        //需要更新isTransitionAnimating，用于处理在过滤时，禁止响应点击，避免界面异常。
        cellModel.transitionAnimating = true;
        __weak typeof(self)weakSelf = self;
        self.animator.progressCallback = ^(CGFloat percent) {
            for (TYSegmentSelectedAnimationBlock block in weakSelf.animationBlockArray) {
                block(percent);
            }
        };
        self.animator.completeCallback = ^{
            cellModel.transitionAnimating = NO;
            [weakSelf.animationBlockArray removeAllObjects];
        };
        [self.animator start];
    }
}

@end
